package com.kidback.bbloc259.ui.map;

import android.Manifest;
import android.graphics.Point;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMapOptions;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MyLocationStyle;
import com.kidback.bbloc259.app.APPConst;
import com.kidback.bbloc259.app.provider.DeviceDataProvider;
import com.kidback.bbloc259.base.BaseFragment;
import com.kidback.bbloc259.bean.LocationBean;
import com.kidback.bbloc259.databinding.ItemAddressBinding;
import com.kidback.bbloc259.databinding.MapFragmentBinding;
import com.kidback.bbloc259.util.CollectionUtils;
import com.kidback.bbloc259.util.DeviceUtils;
import com.kidback.bbloc259.util.TimeUtils;
import com.kidback.bbloc259.util.ToastUtils;
import com.tbruyelle.rxpermissions3.RxPermissions;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;


public class MapFragment extends BaseFragment<MapFragmentBinding> {
    private static final String TAG = "MapFragment";

    private UserMapLayer userMapLayer;

    private AMapLocationClient client;

    private AddressAdapter adapter = new AddressAdapter();

    @Override
    public MapFragmentBinding getViewBinding(ViewGroup container) {
        return MapFragmentBinding.inflate(inflater);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        viewBinding.mapView.onCreate(savedInstanceState);

        return view;
    }

    @Override
    protected void initView() {

        userMapLayer = new UserMapLayer(this, viewBinding.mapView);
        userMapLayer.init();

        viewBinding.mapView.getMap().getUiSettings().setRotateGesturesEnabled(false);
        viewBinding.mapView.getMap().getUiSettings().setMyLocationButtonEnabled(false);

        viewBinding.btnLocPermission.setOnClickListener(onClickListener);
        viewBinding.imgMyLocation.setOnClickListener(onClickListener);
        viewBinding.btnMockTest.setOnClickListener(onClickListener);

        MyLocationStyle myLocationStyle;
        myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点，定位点依照设备方向旋转，并且会跟随设备移动。（1秒1次定位）如果不设置myLocationType，默认也会执行此种模式。
        myLocationStyle.showMyLocation(true);
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
        myLocationStyle.interval(1000); //设置连续定位模式下的定位间隔，只在连续定位模式下生效，单次定位模式下不会生效。单位为毫秒。
        viewBinding.mapView.getMap().setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
        viewBinding.mapView.getMap().getUiSettings().setMyLocationButtonEnabled(false);
        viewBinding.mapView.getMap().setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点，false表示隐藏定位蓝点并不进行定位，默认是false。
        viewBinding.mapView.getMap().getUiSettings().setZoomPosition(AMapOptions.ZOOM_POSITION_RIGHT_CENTER);
        viewBinding.mapView.getMap().getUiSettings().setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_LEFT);

        viewBinding.mapView.getMap().moveCamera(CameraUpdateFactory.zoomTo(APPConst.MAP_ZOOM_DEFAULT));
        //CameraPosition cameraPosition = new CameraPosition(new LatLng(39.977290,116.337000),18,30,0);
        //viewBinding.mapView.getMap().moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

        viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        viewBinding.recyclerView.setAdapter(adapter);

        if (APPConst.MOCK_MODE) {
            viewBinding.btnMockTest.setVisibility(View.VISIBLE);
        } else {
            viewBinding.btnMockTest.setVisibility(View.GONE);
        }

        try {
            client = new AMapLocationClient(getActivity());
            client.setLocationListener(new AMapLocationListener() {
                @Override
                public void onLocationChanged(AMapLocation aMapLocation) {
                    Log.e(TAG, aMapLocation.toString());

                    if (APPConst.MOCK_MODE) {
                        //模拟测试模式，不使用高德定位
                    } else {
                        userMapLayer.addMyPoint(aMapLocation);

                        //过滤无效数据
                        if (aMapLocation.getLatitude() == 0f || aMapLocation.getLongitude() == 0f) {
                            return;
                        }

                        LocationBean locationBean = new LocationBean();
                        locationBean.create_time = TimeUtils.convert(aMapLocation.getTime(), TimeUtils.TIME_FORMAT_YYYY_MM_DD_HH_MM_SS_2);
                        locationBean.latitude = aMapLocation.getLatitude();
                        locationBean.longitude = aMapLocation.getLongitude();
                        locationBean.address = aMapLocation.getAddress();
                        adapter.append(locationBean);
                    }

                }
            });
            client.startLocation();
        } catch (Exception e) {
            e.printStackTrace();
        }

        refreshLocUI();
    }

    @Override
    protected void loadData() {

    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        //在activity执行onDestroy时执行mMapView.onDestroy()，销毁地图
        viewBinding.mapView.onDestroy();
    }

    @Override
    public void onStart() {
        super.onStart();
        //在activity执行onResume时执行mMapView.onResume ()，重新绘制加载地图
        viewBinding.mapView.onResume();
    }

    @Override
    public void onStop() {
        super.onStop();
        //在activity执行onPause时执行mMapView.onPause ()，暂停地图的绘制
        viewBinding.mapView.onPause();
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        viewBinding.mapView.onSaveInstanceState(savedInstanceState);
    }

    private void refreshLocUI() {
        if (!this.isAdded()) {
            return;
        }

        RxPermissions rxPermissions = new RxPermissions(this);
        boolean isLocPermissionGranted = rxPermissions.isGranted(Manifest.permission.ACCESS_FINE_LOCATION);
        if (!isLocPermissionGranted) {
            viewBinding.layoutLocationTip.setVisibility(View.VISIBLE);
            viewBinding.tvLocPermission.setVisibility(View.VISIBLE);
            viewBinding.btnLocPermission.setVisibility(View.VISIBLE);
            viewBinding.tvLocSwitch.setVisibility(View.GONE);
            viewBinding.btnLocSwitch.setVisibility(View.GONE);
        } else if (!DeviceUtils.isLocationEnabled()) {
            viewBinding.layoutLocationTip.setVisibility(View.VISIBLE);
            viewBinding.tvLocPermission.setVisibility(View.GONE);
            viewBinding.tvLocPermission.setVisibility(View.GONE);
            viewBinding.btnLocPermission.setVisibility(View.GONE);
            viewBinding.tvLocSwitch.setVisibility(View.VISIBLE);
            viewBinding.btnLocSwitch.setVisibility(View.VISIBLE);
        } else {
            viewBinding.layoutLocationTip.setVisibility(View.GONE);
        }

    }


    private View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (v == viewBinding.btnLocPermission) {
                RxPermissions rxPermissions = new RxPermissions(MapFragment.this);

                Disposable d = rxPermissions
                        .request(Manifest.permission.ACCESS_FINE_LOCATION)
                        .subscribe(new Consumer<Boolean>() {
                            @Override
                            public void accept(Boolean granted) throws Exception {
                                if (granted) {
                                    refreshLocUI();
                                    client.startLocation();
                                } else {
                                    //暂时不判断是否 “禁止且不再提醒”
                                    ToastUtils.show("未授予定位存储权限");
                                }
                            }
                        });

            } else if (v == viewBinding.btnMockTest) {

                if (APPConst.MOCK_MODE) {
                    Point point = new Point();
                    point.x = viewBinding.mapView.getWidth() / 2;
                    point.y = viewBinding.mapView.getHeight() / 2;

                    LatLng centerLatLngGCJ = viewBinding.mapView.getMap().getProjection().fromScreenLocation(point);

                    AMapLocation aMapLocation = new AMapLocation("gps");
                    aMapLocation.setLatitude(centerLatLngGCJ.latitude);
                    aMapLocation.setLongitude(centerLatLngGCJ.longitude);
                    aMapLocation.setTime(System.currentTimeMillis());
                    aMapLocation.setAddress("深圳市南山区桃园路");

                    userMapLayer.addMyPoint(aMapLocation);

                }
            } else if (v == viewBinding.imgMyLocation) {

                if (DeviceDataProvider.getInst().get() != null &&
                        DeviceDataProvider.getInst().get().lastLocation != null) {
                    AMapLocation aMapLocation = DeviceDataProvider.getInst().get().lastLocation;

                    LatLng latLng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                    /**
                     * CameraPosition 第一个参数： 目标位置的屏幕中心点经纬度坐标。
                     * CameraPosition 第二个参数： 目标可视区域的缩放级别
                     * CameraPosition 第三个参数： 目标可视区域的倾斜度，以角度为单位。
                     * CameraPosition 第四个参数： 可视区域指向的方向，以角度为单位，从正北向顺时针方向计算，从0度到360度
                     */
                    float zoom = viewBinding.mapView.getMap().getCameraPosition().zoom;
                    CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(latLng, zoom, 0, 0));
                    viewBinding.mapView.getMap().animateCamera(cameraUpdate);

                }

            }

        }
    };


    private class AddressVH extends RecyclerView.ViewHolder {

        public com.kidback.bbloc259.databinding.ItemAddressBinding binding;

        public AddressVH(com.kidback.bbloc259.databinding.ItemAddressBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }

    private class AddressAdapter extends RecyclerView.Adapter<AddressVH> {

        private List<LocationBean> dataList = new ArrayList<>();

        public AddressAdapter() {
        }

        public void append(LocationBean locationBean) {
            dataList.add(0, locationBean);
            notifyItemInserted(0);
        }

        @NonNull
        @Override
        public AddressVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            ItemAddressBinding binding = ItemAddressBinding.inflate(LayoutInflater.from(getActivity()), parent, false);
            AddressVH vh = new AddressVH(binding);

            return vh;
        }

        @Override
        public void onBindViewHolder(@NonNull AddressVH holder, int position) {

            holder.binding.tvTime.setText(CollectionUtils.get(dataList, position).create_time);
            holder.binding.tvLatitude.setText(String.valueOf(CollectionUtils.get(dataList, position).latitude));
            holder.binding.tvLongitude.setText(String.valueOf(CollectionUtils.get(dataList, position).longitude));
            holder.binding.tvAddress.setText(String.valueOf(CollectionUtils.get(dataList, position).address));

        }

        @Override
        public int getItemCount() {
            return CollectionUtils.size(dataList);
        }

    }

}
